using System;
using System.Collections.Generic;
using FireStarter.Base;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.Base.Exceptions;
using Habanero.BO;
using Habanero.Smooth;
using NUnit.Framework;
using Rhino.Mocks;

namespace FireStarterModeller.Test.BO
{
    /// <summary>
    /// Provides a place to write custom tests for DMUniqueConstraintProperty objects.
    /// This file is only written once and can be changed.  The Def file
    /// attached to this as a dependent is rewritten with each regeneration
    /// and contains the standard tests for DMUniqueConstraintProperty.
    /// Regenerate this test project whenever there have been changes to the
    /// business objects.
    /// If tests are failing due to a unique setup in your application,
    /// you can either override the Create methods in TestUtils, or you
    /// can add the test to the ignore list below and reimplement it here.
    /// </summary>
    public partial class TestDMUniqueConstraintProperty
    {
        [SetUp]
        public override void SetupTest()
        {
            //Runs every time that any testmethod is executed
            base.SetupTest();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //------------------------------------------------------------
            // Use this list to ignore generated tests that are failing
            // due to a unique condition in your application.
            // Remember to reimplement the test here.
            //------------------------------------------------------------
            //_ignoreList.Add("TestMethodName", "Reason for ignoring it");
            base.SetupFixture();
        }

        [TearDown]
        public override void TearDownTest()
        {
            //runs every time any testmethod is complete
            base.TearDownTest();
        }
        [Test]
        public void Test_ToString()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintProperty dmUniqueConstraintProperty = TestUtilsDMUniqueConstraintProperty.CreateUnsavedValidDMUniqueConstraintProperty();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmUniqueConstraintProperty.UniqueConstraint);
            Assert.IsNotNull(dmUniqueConstraintProperty.Property);
            //---------------Execute Test ----------------------
            string actualToString = dmUniqueConstraintProperty.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual(dmUniqueConstraintProperty.UniqueConstraint + " - " + dmUniqueConstraintProperty.Property, actualToString);
        }

        [Test]
        public void Test_ToString_UniqueConstraintNull()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintProperty dmUniqueConstraintProperty = TestUtilsDMUniqueConstraintProperty.CreateUnsavedValidDMUniqueConstraintProperty_WNullUniqueConstraint();
            dmUniqueConstraintProperty.UniqueConstraint = null;
            //---------------Assert Precondition----------------
            Assert.IsNull(dmUniqueConstraintProperty.UniqueConstraint);
            Assert.IsNotNull(dmUniqueConstraintProperty.Property);
            //---------------Execute Test ----------------------
            string actualToString = dmUniqueConstraintProperty.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual( " - " + dmUniqueConstraintProperty.Property, actualToString);
        }
        [Test]
        public void Test_ToString_PropertyNull()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintProperty dmUniqueConstraintProperty = TestUtilsDMUniqueConstraintProperty.CreateUnsavedValidDMUniqueConstraintProperty();
            dmUniqueConstraintProperty.Property = null;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmUniqueConstraintProperty.UniqueConstraint);
            Assert.IsNull(dmUniqueConstraintProperty.Property);
            //---------------Execute Test ----------------------
            string actualToString = dmUniqueConstraintProperty.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual(dmUniqueConstraintProperty.UniqueConstraint + " - " , actualToString);
        }
        [Test]
        public void Test_ToString_PropertyNull_UniqueConstraintNull()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintProperty dmUniqueConstraintProperty = TestUtilsDMUniqueConstraintProperty.CreateUnsavedValidDMUniqueConstraintProperty_WNullUniqueConstraint();
            dmUniqueConstraintProperty.UniqueConstraint = null;
            dmUniqueConstraintProperty.Property = null;
            //---------------Assert Precondition----------------
            Assert.IsNull(dmUniqueConstraintProperty.UniqueConstraint);
            Assert.IsNull(dmUniqueConstraintProperty.Property);
            //---------------Execute Test ----------------------
            string actualToString = dmUniqueConstraintProperty.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual(dmUniqueConstraintProperty.UniqueConstraintPropertyID.ToString() , actualToString);
        }

        [Test]
        public void Test_ToString_UniqueConstraintPropertyNameNull_UniqueConstraintPropertyIDNull()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintProperty dmUniqueConstraintProperty = TestUtilsDMUniqueConstraintProperty.CreateUnsavedValidDMUniqueConstraintProperty_WNullUniqueConstraint();
            dmUniqueConstraintProperty.Property = null;
            dmUniqueConstraintProperty.UniqueConstraintPropertyID = null;
            //---------------Assert Precondition----------------
            Assert.IsNull(dmUniqueConstraintProperty.UniqueConstraint);
            Assert.IsNull(dmUniqueConstraintProperty.Property);
            Assert.IsNull(dmUniqueConstraintProperty.UniqueConstraintPropertyID);
            //---------------Execute Test ----------------------
            string actualToString = dmUniqueConstraintProperty.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual("-unnamed UniqueConstraintProperty-", actualToString);
        }

        [Test]
        public void Test_InsertNewUniqueConstraintPropertyInfo()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintProperty dmUniqueConstraintProperty = TestUtilsShared.CreateUnsavedValidUniqueConstraintPropertyInfo();

            //---------------Assert Precondition----------------
            Assert.IsTrue(dmUniqueConstraintProperty.Status.IsNew);

            //---------------Execute Test ----------------------
            dmUniqueConstraintProperty.Save();

            //---------------Test Result -----------------------
            Assert.IsFalse(dmUniqueConstraintProperty.Status.IsNew);
        }

        [Test]
        public void Test_InsertNewUniqueConstraintPropertyInfo_Invalid()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintProperty dmUniqueConstraintProperty = new DMUniqueConstraintProperty();

            //---------------Assert Precondition----------------
            Assert.IsTrue(dmUniqueConstraintProperty.Status.IsNew);

            //---------------Execute Test ----------------------
            try
            {
                dmUniqueConstraintProperty.Save();
                Assert.Fail("expected Err");
            }
            //---------------Test Result -----------------------
            catch (BusObjectInAnInvalidStateException ex)
            {
                StringAssert.Contains("Unique Constraint ID' is a compulsory field and has no value", ex.Message);
                StringAssert.Contains("Property' is a compulsory field and has no value", ex.Message);
            }
            Assert.IsTrue(dmUniqueConstraintProperty.Status.IsNew);
        }

        [Test]
        public void Test_DeleteUniqueConstraintPropertyInfo()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintProperty dmUniqueConstraintProperty = TestUtilsShared.CreateSavedUniqueConstraintPropertyInfo();

            //---------------Assert Precondition----------------
            Assert.IsFalse(dmUniqueConstraintProperty.Status.IsNew);
            string message;
            Assert.IsTrue(dmUniqueConstraintProperty.IsDeletable(out message));

            //---------------Execute Test ----------------------
            dmUniqueConstraintProperty.MarkForDelete();
            dmUniqueConstraintProperty.Save();

            //---------------Test Result -----------------------  
            Assert.IsTrue(dmUniqueConstraintProperty.Status.IsNew);
            Assert.IsTrue(dmUniqueConstraintProperty.Status.IsDeleted);
        }

        [Test]
        public void Test_LoadUniqueConstraintPropertyInfo()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintProperty dmUniqueConstraintProperty = TestUtilsShared.CreateSavedUniqueConstraintPropertyInfo();
            BusinessObjectManager.Instance.ClearLoadedObjects();

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DMUniqueConstraintProperty loadedDMUniqueConstraintProperty = Broker.GetBusinessObject<DMUniqueConstraintProperty>(dmUniqueConstraintProperty.ID);

            //---------------Test Result -----------------------  
            Assert.IsFalse(loadedDMUniqueConstraintProperty.Status.IsNew);
            Assert.AreEqual(loadedDMUniqueConstraintProperty.ID, dmUniqueConstraintProperty.ID);
            //TODO: When not using memory db Assert.AreNotSame(loadedDMClass, businessObjectInfo);
        }

        [Test]
        public void Test_IsPartOfSingleUniqueConstraint_WhenIs_ShouldReturnTrue()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateSavedDMClassWithProps();
            DMProperty dmProperty = dmClass.Properties[0];
            DMUniqueConstraint uniqueConstraint = dmClass.UniqueConstraints.CreateBusinessObject();
            uniqueConstraint.AddPropertyInfo(dmProperty);

            //---------------Assert Precondition----------------
            Assert.AreEqual(1,uniqueConstraint.Properties.Count);
            //---------------Execute Test ----------------------
            var ucProp = uniqueConstraint.UniqueConstraintProperties[0];
            var isPartOfSingleUniqueConstraint = ucProp.IsPartOfSingleUniqueConstraint;
            //---------------Test Result -----------------------
            Assert.IsTrue(isPartOfSingleUniqueConstraint);
        }
        [Test]
        public void Test_IsPartOfSingleUniqueConstraint_WhenPartOfComposite_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateSavedDMClassWithProps();
            DMProperty dmProperty = dmClass.Properties[0];
            DMUniqueConstraint uniqueConstraint = dmClass.UniqueConstraints.CreateBusinessObject();
            uniqueConstraint.AddPropertyInfo(dmClass.Properties.CreateBusinessObject());
            uniqueConstraint.AddPropertyInfo(dmProperty);

            //---------------Assert Precondition----------------
            Assert.AreEqual(2,uniqueConstraint.Properties.Count);
            //---------------Execute Test ----------------------
            var ucProp = dmProperty.DMUniqueConstraintProperties[0];
            var isPartOfSingleUniqueConstraint = ucProp.IsPartOfSingleUniqueConstraint;
            //---------------Test Result -----------------------
            Assert.IsFalse(isPartOfSingleUniqueConstraint);
        }

        [Test]
        public void Test_ClassName_WhenHasDMPRop_ShouldReturnDMPropName()
        {
            //---------------Set up test pack-------------------
            DMProperty property = MockRepository.GenerateMock<DMProperty>(ConstructForFakes.True);
            string expectedClassName = TestUtilsShared.GetRandomString();
            property.Stub(dmProperty => dmProperty.ClassName).Return(expectedClassName);
            DMUniqueConstraintProperty ucProp = new DMUniqueConstraintPropertyFake {Property = property};
            //---------------Assert Precondition----------------
            Assert.AreEqual(expectedClassName, property.ClassName);
            //---------------Execute Test ----------------------
            string className = ucProp.ClassName;
            //---------------Test Result -----------------------
            Assert.AreEqual(expectedClassName, className);
        }
        [Test]
        public void Test_ClassName_WhenNotHasDMProp_ShouldReturnEmptyString()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintProperty ucProp = new DMUniqueConstraintProperty();
            //---------------Assert Precondition----------------
            Assert.IsNull(ucProp.Property);
            //---------------Execute Test ----------------------
            string className = ucProp.ClassName;
            //---------------Test Result -----------------------
            Assert.AreEqual("", className);
        }


        [Test]
        public void Test_PropertyName_WhenHasDMPRop_ShouldReturnDMPropName()
        {
            //---------------Set up test pack-------------------
            DMProperty property = MockRepository.GenerateMock<DMProperty>(ConstructForFakes.True);
            string expectePropertyName = TestUtilsShared.GetRandomString();
            property.Stub(dmProperty => dmProperty.PropertyName).Return(expectePropertyName);
            DMUniqueConstraintProperty ucProp = new DMUniqueConstraintPropertyFake { Property = property };
            //---------------Assert Precondition----------------
            Assert.AreEqual(expectePropertyName, property.PropertyName);
            //---------------Execute Test ----------------------
            string propertyName = ucProp.PropertyName;
            //---------------Test Result -----------------------
            Assert.AreEqual(expectePropertyName, propertyName);
        }
        [Test]
        public void Test_PropertyName_WhenNotHasDMProp_ShouldReturnEmptyString()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintProperty ucProp = new DMUniqueConstraintProperty();
            //---------------Assert Precondition----------------
            Assert.IsNull(ucProp.Property);
            //---------------Execute Test ----------------------
            string propertyName = ucProp.PropertyName;
            //---------------Test Result -----------------------
            Assert.AreEqual("", propertyName);
        }
    }

    public class DMUniqueConstraintPropertyFake : DMUniqueConstraintProperty
    {
        [AutoMapIgnore]
        public override DMProperty Property { get; set; }
        protected override IClassDef ConstructClassDef()
        {
            AllClassesAutoMapper.ClassDefCol = Habanero.BO.ClassDefinition.ClassDef.ClassDefs;
            return this.GetType().MapClass();
        }
        [Test]
        public void Test_GetParent()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraint uniqueConstraint = new DMUniqueConstraint();
            DMUniqueConstraintProperty prop = new DMUniqueConstraintProperty();
            uniqueConstraint.UniqueConstraintProperties.Add(prop);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            IModelElement parent = ((IModelElement)prop).Parent;
            //---------------Test Result -----------------------
            Assert.AreSame(uniqueConstraint, parent);
        }

        [Test]
        public void Test_SetParentExceptionThrown()
        {
            //---------------Set up test pack-------------------
            IModelElement prop = new DMUniqueConstraintProperty();

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            Exception exceptionThrown = null;
            try
            {
                prop.Parent = new DMUniqueConstraint();
            }
            catch (Exception ex)
            {
                exceptionThrown = ex;
            }
            //---------------Test Result -----------------------
            Assert.IsNotNull(exceptionThrown);
            Assert.IsInstanceOf(typeof(HabaneroDeveloperException), exceptionThrown);
            StringAssert.Contains
                ("Set the parent of the UniqueConstraintProperty by setting the related UniqueConstraint object",
                 exceptionThrown.Message);
        }
    }
}
